using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Input
{
    public class Input : GameComponent
    {

        Game game;
        InputService service;
        GameWindow window;

        MouseState originalMouseState;

        float rotationSpeed = 0.005f;
        const float moveSpeed = 0.025f;
        const float moveShiftSpeed = 0.05f;

        double prevMilliseconds = 0;

        public Input(Game game) : base(game)
        {
            this.game = game;
            this.service = new InputService();
            this.game.Services.AddService(typeof(InputService), this.service);
        }

        public override void Initialize()
        {

            System.Console.Out.WriteLine("Initializing library \"" + this.GetType().Name + "\"...");

            this.window = this.game.Window;

            Mouse.SetPosition(window.ClientBounds.Width / 2, window.ClientBounds.Height / 2);
            originalMouseState = Mouse.GetState();

            base.Initialize();
            System.Console.Out.WriteLine("Library  \"" + this.GetType().Name + "\" initialized");

        }

        public override void Update(GameTime gameTime)
        {

            if (!this.game.IsActive)
            {
                base.Update(gameTime);
                return;
            }

            double difTime = gameTime.TotalGameTime.TotalMilliseconds - prevMilliseconds;
            prevMilliseconds = gameTime.TotalGameTime.TotalMilliseconds;

            MouseState currentMouseState = Mouse.GetState();

            if (currentMouseState != originalMouseState)
            {

                float xDifference = currentMouseState.X - originalMouseState.X;
                float yDifference = currentMouseState.Y - originalMouseState.Y;
                service.leftRightRot = rotationSpeed * xDifference;
                service.upDownRot = rotationSpeed * yDifference;
                Mouse.SetPosition(window.ClientBounds.Width / 2, window.ClientBounds.Height / 2);
            }
            else
            {
                service.leftRightRot = 0;
                service.upDownRot = 0;
            }

            KeyboardState keyState = Keyboard.GetState();

            service.moveX = 0;
            service.moveY = 0;

            float timedMoveSpeed;
            if (!keyState.IsKeyDown(Keys.LeftShift))
                timedMoveSpeed = (float)(moveSpeed * difTime);
            else
                timedMoveSpeed = (float)(moveShiftSpeed * difTime);

            if (keyState.IsKeyDown(Keys.Up) || keyState.IsKeyDown(Keys.W))
                service.moveX = timedMoveSpeed;
            if (keyState.IsKeyDown(Keys.Down) || keyState.IsKeyDown(Keys.S))
                service.moveX = -timedMoveSpeed;
            if (keyState.IsKeyDown(Keys.Right) || keyState.IsKeyDown(Keys.D))
                service.moveY = timedMoveSpeed;
            if (keyState.IsKeyDown(Keys.Left) || keyState.IsKeyDown(Keys.A))
                service.moveY = -timedMoveSpeed;

        }

    }

    public class InputService
    {

        GameWindow window;

        internal float leftRightRot;
        internal float upDownRot;

        internal float moveX;
        internal float moveY;

        internal InputService()
        {
        }

        public float getMoveForwardBack()
        {
            return moveX;
        }

        public float getMoveLeftRight()
        {
            return moveY;
        }

        public float getRotationLeftRight()
        {
            return leftRightRot;
        }

        public float getRotationUpDown()
        {
            return upDownRot;
        }

    }
}
